#include <iostream>
#include <fstream>
//#include <iomanip>
#include "emp.h"
using std::cout;
using std::string;
using std::cin;
using std::endl;
using std::fstream;
using std::flush;

void eatline() { while(cin.get() != '\n') continue; }

//abstr_emp methods
abstr_emp::abstr_emp() : fname("none"), lname("none"), job("none")
{
}

abstr_emp::abstr_emp(const string & fn, const string & ln, const string & j) : fname(fn), lname(ln), job(j)
{
}

void abstr_emp::ShowAll() const
{
    cout << "First name: " << fname << endl;
    cout << "Last name: " << lname << endl;
    cout << "Job: " << job << endl;
}

void abstr_emp::SetAll()
{
    cout << "Please enter the first name: ";
    cin >> fname;
    eatline();
    cout << "Please enter the last name: ";
    cin >> lname;
    eatline();
    cout << "Please enter your job: ";
   getline(cin, job);
}

void abstr_emp::GetAll(fstream & f)
{
    f >> fname >> lname;
    while(f.get() != '\n') continue;
    getline(f, job);
}

void abstr_emp::WriteAll(std::fstream & f)
{
    f << fname << " " << lname << endl;;
    f << job << endl;
    f << flush;
}

std::ostream & operator<<(std::ostream & os, const abstr_emp & e)
{
    os << "First name: " << e.fname << endl;
    os << "Last name: " << e.lname << endl;
    return os;
}

abstr_emp::~abstr_emp()
{
}

//employee methods
employee::employee() : abstr_emp()
{
}

employee::employee(const string & fn, const string &ln, const string &j) : abstr_emp(fn, ln, j)
{
}

void employee::ShowAll() const
{
    abstr_emp::ShowAll();
}

void employee::SetAll()
{
    abstr_emp::SetAll();
}

void employee::GetAll(fstream & f)
{
    abstr_emp::GetAll(f);
}

void employee::WriteAll(std::fstream & f)
{
    abstr_emp::WriteAll(f);
    f << flush;
}

//manager methods
manager::manager() : abstr_emp()
{
}

manager::manager(const string &fn, const string &ln, const string & j, int ico) : abstr_emp(fn, ln, j), inchargeof(ico)
{
}

manager::manager(const abstr_emp & e, int ico) :abstr_emp(e), inchargeof(ico)
{
}

manager::manager(const manager & m) : abstr_emp(m), inchargeof(m.inchargeof)
{
}

void manager::ShowAll() const
{
    abstr_emp::ShowAll();
    cout << "InChargeOf: " << inchargeof << endl;
}

void manager::SetAll()
{
    abstr_emp::SetAll();
    cout << "Please enter the InChargeOf: ";
    cin >> inchargeof;
    eatline();
}

void manager::GetAll(fstream & f)
{
    abstr_emp::GetAll(f);
    f >> inchargeof;
}

void manager::WriteAll(std::fstream & f)
{
    abstr_emp::WriteAll(f);
    f << inchargeof << endl;
    f << flush;
}

//fink methods
fink::fink() : abstr_emp()
{
}

fink::fink(const string &fn, const string & ln, const string &j, const string &rpo) : abstr_emp(fn, ln, j), reportsto(rpo)
{
}

fink::fink(const abstr_emp & e, const string & rpo) : abstr_emp(e), reportsto(rpo)
{
}

fink::fink(const fink & e) : abstr_emp(e), reportsto(e.reportsto)
{
}

void fink::ShowAll() const
{
    abstr_emp::ShowAll();
    cout << "Reportsto: " << reportsto << endl;
}

void fink::SetAll()
{
    abstr_emp::SetAll();
    cout << "Please enter the reportsto: ";
    getline(cin, reportsto);
}

void fink::GetAll(fstream & f)
{
    abstr_emp::GetAll(f);
    getline(f, reportsto);
}

void fink::WriteAll(std::fstream & f)
{
    abstr_emp::WriteAll(f);
    f << reportsto << endl;
    f << flush;
}

//highfink methods
highfink::highfink() : abstr_emp(), manager(), fink()
{
}

highfink::highfink(const string & fn, const string & ln, const string j, const string & rpo, int ico) :
                                                    abstr_emp(fn, ln, j), manager(fn, ln, j, ico), fink(fn, ln, j, rpo)
{
}

highfink::highfink(const fink & f, int ico) : abstr_emp(f), manager(f, ico), fink(f)
{
}

highfink::highfink(const manager & m, const string & rpo) : abstr_emp(m), manager(m), fink(m, rpo)
{
}

highfink::highfink(const highfink & h) : abstr_emp(h), manager(h), fink(h)
{
}

void highfink::ShowAll() const
{
    abstr_emp::ShowAll();
    cout << "InChargeOf: " << manager::InChargeOf() << endl;
    cout << "Reportsto: " << fink::ReportsTo() << endl;
}

void highfink::SetAll()
{
    abstr_emp::SetAll();
    cout << "Please enter the InChargeOf: ";
    cin >> manager::InChargeOf();
    eatline();
    cout << "Please enter the reportsto: ";
    getline(cin, fink::ReportsTo());
}

void highfink::GetAll(fstream & f)
{
    abstr_emp::GetAll(f);
    f >> manager::InChargeOf();
    getline(f, fink::ReportsTo());
}

void highfink::WriteAll(std::fstream & f)
{
    abstr_emp::WriteAll(f);
    f << manager::InChargeOf() << endl;
    f << fink::ReportsTo() << endl;
    f << flush;
}
